/**
 * AbstractModel.java
 * 
 * Created in 2008-1-17
 */
package org.onionframework.persistence.model;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;

import org.apache.commons.lang.ObjectUtils;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.TypeDef;
import org.hibernate.annotations.TypeDefs;
import org.onionframework.persistence.model.annotation.Property;
import org.onionframework.persistence.model.annotation.Utility;
import org.onionframework.persistence.model.support.XMLType;
import org.springframework.orm.hibernate3.support.BlobByteArrayType;
import org.springframework.orm.hibernate3.support.ClobStringType;

/**
 * 自定义model类的父类，提供了id的生成方式，及重写了hashcode、equals方法</br>
 * 持久化模型抽象实现，主要是确定主键生成机制，添加通用的hashcode、equals方法。
 * 
 * @author Yang XuePing
 * @author allan zhang
 * @version 1.0
 */
@MappedSuperclass
@TypeDefs( {@TypeDef(name = "xml", typeClass = XMLType.class),
		@TypeDef(name = "clobString", typeClass = ClobStringType.class),
		@TypeDef(name = "blobByteArray", typeClass = BlobByteArrayType.class) })
public abstract class AbstractModel implements Model<String>,Serializable {

	/** 序列化序号 */
	private static final long serialVersionUID = -3833640713920205968L;

	/** 主键 */
	private String id;

	/** 创建日期,默认为当前时间 */
	private Date createTime = new Date();

	private Integer version;

	@Id
	@Column(name = "ID", length = 50)
	@GeneratedValue(generator = "onion-uuid")
	@GenericGenerator(name = "onion-uuid", strategy = "org.onionframework.persistence.model.support.UUIDGenerator")
	@Property(name="标识")
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	/**
	 * @return the createTime
	 */
	@Property(name="创建时间")
	public Date getCreateTime() {
		return createTime;
	}

	/**
	 * @param createTime
	 *            the createTime to set
	 */
	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	@Version
	@Column(name = "VERSION", nullable = false)
	@Utility
	public Integer getVersion() {
		return version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (!(o instanceof AbstractModel)) {
			return false;
		}
		AbstractModel model = (AbstractModel) o;
		return ObjectUtils.equals(id, model.getId());
	}

	public int hashCode() {
		return ObjectUtils.hashCode(id);
	}

	public String toString() {
		return this.getClass().getName() + "#" + id;
	}
}
